package top.mingyi4cjh.cms.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import top.mingyi4cjh.cms.common.configuration.AccessLimit;
import top.mingyi4cjh.cms.common.error.BusinessException;
import top.mingyi4cjh.cms.common.error.EmBusinessError;
import top.mingyi4cjh.cms.common.response.CommonReturnType;
import top.mingyi4cjh.cms.common.utils.UserInfoUtils;
import top.mingyi4cjh.cms.dataobject.ArticleApprovalDO;
import top.mingyi4cjh.cms.model.ArticleModel;
import top.mingyi4cjh.cms.service.ArticleService;
import top.mingyi4cjh.cms.viewobject.ArticleVO;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static top.mingyi4cjh.cms.common.utils.Field.ADMIN;
import static top.mingyi4cjh.cms.common.utils.Field.LOGIN_USER;
import static top.mingyi4cjh.cms.common.utils.UuidManager.UUID_MANAGER;

/**
 * @author MingYi
 * @program cms
 * @create 2022/04/30 18:21
 */
@Api
@RestController("article")
@RequestMapping(value = "/article", method = {RequestMethod.GET, RequestMethod.POST})
public class ArticleController extends BaseController {
    @Resource
    private HttpServletRequest request;

    @Resource
    private ArticleService articleService;

    @Resource
    private UserInfoUtils userInfoUtils;

    @ApiOperation(value = "新建文章")
    @AccessLimit
    @PostMapping(value = "/create", consumes = {CONTENT_TYPE_FORMED})
    public CommonReturnType createArticle(String title, String content, String columnId) {
        if (StringUtils.isEmpty(title) || StringUtils.isEmpty(content)) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
        }

        String userId = userInfoUtils.getLoginUserId(request);
        ArticleModel articleModel = new ArticleModel();
        articleModel.setArticleId(UUID_MANAGER.getUuid());
        articleModel.setAuthorId(Long.valueOf(userId));
        articleModel.setTitle(title);
        articleModel.setContent(content);
        articleModel.setUploadTime(new Date(System.currentTimeMillis()));
        if (!StringUtils.isEmpty(columnId)) {
            articleModel.setColumnId(Long.valueOf(columnId));
        }

        articleService.createArticle(articleModel);

        return CommonReturnType.create(null);
    }

    @ApiOperation(value = "获取文章信息")
    @AccessLimit
    @PostMapping(value = "/get", consumes = {CONTENT_TYPE_FORMED})
    public CommonReturnType getArticle(String articleId) {
        logger.info("articleId: {}", articleId);
        String token = request.getHeader("token");
        logger.debug("token: {}", token);

        if (StringUtils.isEmpty(articleId)) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
        }

        ArticleModel result = articleService.getArticle(Long.valueOf(articleId));
        return CommonReturnType.create(convertVoFromModel(result));
    }

    @ApiOperation(value = "删除文章")
    @AccessLimit
    @PostMapping(value = "/delete", consumes = {CONTENT_TYPE_FORMED})
    public CommonReturnType deleteArticle(String articleId) {
        if (StringUtils.isEmpty(articleId)) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
        }
        String userId = userInfoUtils.getLoginUserId(request);
        if (!articleService.isArticleOwner(Long.valueOf(userId), Long.valueOf(articleId))) {
            throw new BusinessException(EmBusinessError.ARTICLE_OWNER_FAIL);
        }

        articleService.deleteArticle(Long.valueOf(articleId));

        return CommonReturnType.create(null);
    }

    @ApiOperation(value = "获取自身的文章列表")
    @AccessLimit
    @GetMapping(value = "/getSelfList")
    public CommonReturnType getSelfList() {
        String userId = userInfoUtils.getLoginUserId(request);

        List<ArticleModel> articleModels = articleService.getSelfList(Long.valueOf(userId));
        List<ArticleVO> result = articleModels.stream().map(this::convertVoFromModel).collect(Collectors.toList());

        return CommonReturnType.create(result);
    }

    @ApiOperation(value = "获取未审核文章列表")
    @AccessLimit
    @GetMapping(value = "/getNotApprovalList")
    public CommonReturnType getNotApprovalList() {
        String loginUserId = userInfoUtils.getLoginUserId(request);
        int identify = articleService.queryIdentify(Long.valueOf(loginUserId));
        if (!(identify == ADMIN)) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
        }
        List<ArticleApprovalDO> notApprovalList = articleService.getNotApprovalList();
        List<Long> result = notApprovalList.stream().map(this::cutOutArticleId).collect(Collectors.toList());
        return CommonReturnType.create(result);
    }

    @ApiOperation(value = "审核操作")
    @AccessLimit
    @PostMapping(value = "/approval", consumes = {CONTENT_TYPE_FORMED})
    public CommonReturnType approvalArticle(String articleId, String status) {
        if (StringUtils.isEmpty(articleId) || StringUtils.isEmpty(status)) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
        }
        // 鉴权
        String loginUserId = userInfoUtils.getLoginUserId(request);
        int identify = articleService.queryIdentify(Long.valueOf(loginUserId));
        if (!(identify == ADMIN)) {
            throw new BusinessException(EmBusinessError.UNAUTHORIZED_OPERATION);
        }

        articleService.approval(Long.valueOf(articleId), Integer.valueOf(status), Long.valueOf(loginUserId));
        return CommonReturnType.create(null);
    }

    private ArticleVO convertVoFromModel(ArticleModel articleModel) {
        if (articleModel == null) {
            return null;
        }
        ArticleVO articleVO = new ArticleVO();
        BeanUtils.copyProperties(articleModel, articleVO);
        return articleVO;
    }

    private Long cutOutArticleId(ArticleApprovalDO articleApprovalDO) {
        if (articleApprovalDO == null) {
            return null;
        }

        return articleApprovalDO.getArticleId();
    }
}
